package juego;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;

public abstract class Movil extends Ubicable{
	
	//atributos de instancia	
	protected boolean vivo;
		
	//metodos
	public Movil(int x , int y) {
		super (x,y);
		this.vivo = true;		
	};
	
	public boolean estaVivo(){
		return this.vivo;
	};
	
	//retorna false por defecto. sera redefinidio por proyectil y Tripulado
	public boolean verLealtad(){
		return false;
	};
	
	protected void destruirse(ArrayList<Movil> lista){
		lista.remove(this);
		this.vivo = false;
	};
	
	//Retorna el puntaje acumulado por la destruccion de este y otros moviles.
	//Este metodo se encarga de llamar al metodo destruirse.
	protected int impactar(ArrayList<Movil> listaDeMoviles, ArrayList<Botin> listaDeBotines){
		Queue<Movil> cola = this.acolarMoviles(listaDeMoviles);
		int puntaje = this.vivirMovilesAcolados(cola, listaDeMoviles, listaDeBotines);
		return puntaje;
	}
	
	//inserta los moviles en una cola
	protected Queue<Movil> acolarMoviles(ArrayList<Movil> listaDeMoviles){
		Iterator<Movil> iterador = listaDeMoviles.iterator();
		Queue<Movil> cola = new LinkedList<Movil>();
		while (iterador.hasNext()){
			Movil movil = iterador.next();
			cola.add(movil);
		}
		return cola;
	}
	
	//impacta contra los otros moviles si corresponde.
	//recibe Queue<Movil> cola
	//devuelve el puntaje acumulado
	protected int vivirMovilesAcolados(Queue<Movil> cola, ArrayList<Movil> listaDeMoviles, ArrayList<Botin> listaDeBotines){
		int puntajeAcumulado = 0;
		boolean seguir = true;
		Movil movil;
		while (seguir){
			try{
				movil = cola.remove();
				if (movil.estaVivo()){
					try{
						if (movil.huboContacto(this)){
							//diferente para cada movil
							puntajeAcumulado += this.impactoPropio(movil, listaDeMoviles, listaDeBotines);
						}
					}
					//si se compara con si mismo
					catch (ExcepcionMismoElemento eme){}
				}
			}
			//si la cola esta vacia
			catch (Exception colaVacia){
				seguir = false;
			}
		}//sale del ciclo
		
		puntajeAcumulado += this.verificarDestruccion(listaDeMoviles, listaDeBotines);
						
		return puntajeAcumulado;
	}
	
	public abstract Impacto impactoProvocado();
	
	public abstract boolean esNaveEnemiga();
	
	public abstract boolean esProyectil();
	
	//se elimina de la lista si corresponde. agrega botines a la lista si corresponde. devuelve el puntaje
	public abstract int recibirImpacto(Impacto impacto, ArrayList<Movil> listaDeMoviles, ArrayList<Botin> listaDeBotines);

	public abstract int vivir(ArrayList<Movil> listaDeMoviles,
			ArrayList<Botin> listaDeBotines);
	
	//retorna el puntaje
	protected abstract int impactoPropio(Movil movil, ArrayList<Movil> listaDeMoviles, ArrayList<Botin> listaDeBotines);
	
	//retorna el puntaje
	protected abstract int verificarDestruccion(ArrayList<Movil> listaDeMoviles, ArrayList<Botin> listaDeBotines);
			
}
